home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / out18com.zip / POPUP.INC < prev    next >
Text File  |  1993-01-04  |  9KB  |  391 lines

  1.  
  2. const popup_tag: string[90]
  3.    = #0'@(#)CURRENT_FILE LAST_UPDATE Pop-up window/fast display library 1.0'#0;
  4. #log Pop-up window/fast display library 1.0
  5.  
  6. (*
  7.  * popup - utility library for simple "pop-up" windows
  8.  *
  9.  * written by Samuel H. Smith, 7-Feb-86
  10.  *
  11.  *)
  12.  
  13. const
  14.    low_attr:  integer = 14;
  15.    norm_attr: integer = 15;
  16.    back_attr: integer = 1;
  17.  
  18.    slowdisplay:      boolean = false;
  19.    default_disp_seg: integer = $B800;
  20.  
  21. type
  22.    popup_string = string[255];
  23.  
  24.    screenloc =         record
  25.          character:          char;
  26.          attribute:          byte;
  27.    end;
  28.  
  29.    videoram =          array [0..1999] of screenloc;
  30.    videoptr =          ^videoram;
  31.  
  32.    window_rec = record
  33.       x1,y1,x2,y2: integer;
  34.       attr:        byte;
  35.    end;
  36.  
  37.    window_save_rec = record
  38.       win:      window_rec;
  39.       scr:      videoram;
  40.       cux,cuy:  integer;
  41.    end;
  42.  
  43.  
  44. var
  45.    cur_window:   window_rec;
  46.    saved_window: window_save_rec;
  47.    disp_mem:     videoptr;
  48.    disp_seg:     integer;
  49.  
  50.  
  51. procedure determine_video_ptr;     {determine video display area when
  52.                                     running under DESQview - also works
  53.                                     without DESQview}
  54. const
  55.    video_ptr_known: boolean = false;
  56. begin
  57.  
  58. {   if video_ptr_known then exit; }
  59.  
  60.    disp_seg := default_disp_seg;
  61.  
  62.    inline( $55/                    {push bp}
  63.            $a1/disp_seg/           {mov ax,[disp_seg]}
  64.            $8e/$c0/                {mov es,ax}
  65.            $bf/$00/$00/            {mov di,0}
  66.            $b4/$fe/                {mov ah,fe}
  67.            $cd/$10/                {int 10h}
  68.            $5d/                    {pop bp}
  69.            $8c/$06/disp_seg);      {mov [disp_seg],es}
  70.  
  71.    disp_mem := ptr(disp_seg,0);
  72.    video_ptr_known := true;
  73. end;
  74.  
  75.  
  76. procedure normvideo;
  77. begin
  78.    textcolor(norm_attr);
  79.    textbackground(back_attr);
  80.    cur_window.attr := norm_attr + back_attr shl 4;
  81. end;
  82.  
  83.  
  84. procedure lowvideo;
  85. begin
  86.    textcolor(low_attr);
  87.    textbackground(back_attr);
  88.    cur_window.attr := low_attr + back_attr shl 4;
  89. end;
  90.  
  91.  
  92.  
  93. procedure old_window(win: window_rec);   {redefine the old window
  94.                                           command so it can still be
  95.                                           used by other procs}
  96. begin
  97.    with win do
  98.       window(x1,y1,x2,y2);
  99. end;
  100.  
  101.  
  102.  
  103. procedure window(a1,b1,a2,b2: integer);    {make a new version of window
  104.                                             that saves the current state}
  105. begin
  106.    determine_video_ptr;
  107.  
  108.    with cur_window do
  109.    begin
  110.       x1 := a1;
  111.       y1 := b1;
  112.       x2 := a2;
  113.       y2 := b2;
  114.    end;
  115.  
  116.    old_window(cur_window);
  117. end;
  118.  
  119.  
  120.  
  121. function make_string(c: char; len: integer): popup_string;
  122.                                    {make a string by repeating
  123.                                     a character n times}
  124. var
  125.    i:  integer;
  126.    s:  popup_string;
  127. begin
  128.    for i := 1 to len do
  129.       s[i] := c;
  130.  
  131.    s[0] := chr(len);
  132.    make_string := s;
  133. end;
  134.  
  135.  
  136.  
  137. function invisible: boolean;   {is this the invisible program under doubledos?}
  138. var
  139.    reg:  regpack;
  140.  
  141. begin
  142.    determine_video_ptr;
  143.  
  144.    reg.ax := $e400;   {doubledos return program status}
  145.    msdos(reg);
  146.  
  147.    if (lo(reg.ax) = 2) or slowdisplay then
  148.       invisible := true
  149.    else
  150.       invisible := false;
  151. end;
  152.  
  153.  
  154.  
  155. procedure disp (s:                  popup_string);
  156.                                      {very fast dma string display}
  157. var
  158.    index:              integer;
  159.    i:                  integer;
  160.    c:                  char;
  161.    len:                integer;
  162.    max_index:          integer;
  163.  
  164. begin
  165.  
  166.  
  167.    if invisible or (length(s) < 4) then
  168.                      {can't do dma screens if invisble under doubledos.
  169.                       this is slower than write for short strings}
  170.    begin
  171.       write(s);
  172.       exit;
  173.    end;
  174.  
  175.  
  176.    with cur_window do
  177.    begin
  178.       len := length (s);
  179.       index :=(wherey + y1 - 2)* 80 +(wherex + x1 - 2);
  180.       max_index := y2*80;
  181.  
  182.       for i := 1 to len do
  183.       begin
  184.          c := s [i];
  185.  
  186.          case c of
  187.             ^H:   index := index - 1;
  188.  
  189.             ^J:   begin
  190.                      index := index + 80;
  191.                      if index >= max_index then
  192.                      begin
  193.                         write(^J);
  194.                         index := index - 80;
  195.                      end;
  196.                   end;
  197.  
  198.             ^M:   index :=(index div 80)* 80 + x1 - 1;
  199.  
  200.             ^G:   write(^G);
  201.  
  202.             else  begin
  203.                      with disp_mem^[index] do
  204.                      begin
  205.                         character := c;
  206.                         attribute := attr;
  207.                      end;
  208.  
  209.                      index := index + 1;
  210.  
  211.                      if index >= max_index then
  212.                      begin
  213.                         index := index - 80;
  214.                         writeln;
  215.                      end;
  216.                   end;
  217.          end;
  218.       end;
  219.  
  220.  
  221. (* place cursor at end of displayed string *)
  222.  
  223.       gotoxy((index mod 80)- x1 + 2,(index div 80)- y1 + 2);
  224.    end;
  225. end;
  226.  
  227.  
  228.  
  229. procedure displn(s: popup_string);       {fast display and linefeed}
  230. begin
  231.    disp(s);
  232.    writeln;
  233. end;
  234.  
  235.  
  236.  
  237. procedure open_pop_up(x1,y1,x2,y2: integer; title: popup_string);
  238.                                             {open a titled pop up window
  239.                                              and save previous screen
  240.                                              state so it can be restored}
  241. const
  242.    topleft =           #213;
  243.    topright =          #184;
  244.    botleft =           #212;
  245.    botright =          #190;
  246.    sides =             #179;
  247.    tops =              #205;
  248.  
  249. var
  250.    i,
  251.    j:                  integer;
  252.    side:               popup_string;
  253.    top:                popup_string;
  254.    bottom:             popup_string;
  255.  
  256. begin
  257.  
  258. (* save the current window so it can be restored later *)
  259.    determine_video_ptr;
  260.    saved_window.scr := disp_mem^;
  261.    saved_window.win := cur_window;
  262.    saved_window.cux := wherex;
  263.    saved_window.cuy := wherey;
  264.    window(1,1,80,25);
  265.  
  266.  
  267. (* create window section strings *)
  268.    if title <> '' then
  269.       title := ' ' + title + ' ';
  270.                               {leave spaces around the title, if any}
  271.  
  272.  
  273. (* top of frame *)
  274.    top := make_string (tops, x2 - length (title)- x1 - 2) + topright;
  275.  
  276.  
  277. (* sides of frame *)
  278.    side := '';
  279.    j := 1;
  280.  
  281.    for i :=(y1 + 1) to (y2 - 1) do
  282.    begin
  283.       side[j]:= sides;
  284.       side[j + 1]:=^H;
  285.       side[j + 2]:=^J;
  286.       j := j + 3;
  287.    end;
  288.  
  289.    side[0]:= chr (j - 1);
  290.  
  291.  
  292. (* bottom of frame *)
  293.    bottom := botleft + make_string (tops, x2 - x1 - 1)+ botright;
  294.  
  295.  
  296. (* draw the frame *)
  297.    gotoxy(x1, y1);
  298.    disp(topleft + tops + title + top);
  299.  
  300.    gotoxy(x1, y1 + 1);
  301.    disp(side);
  302.  
  303.    gotoxy(x2, y1 + 1);
  304.    disp(side);
  305.  
  306.    gotoxy(x1, y2);
  307.    disp(bottom);
  308.  
  309. (* define the new window.  let the caller decide if it needs clearing *)
  310.    window(x1+1,y1+1,x2-1,y2-1);
  311.  
  312. end;
  313.  
  314.  
  315.  
  316. procedure remove_pop_up;        {restore the screen like it was
  317.                                  before the popup window was opened}
  318. begin
  319.  
  320. (* restore the windowing settings *)
  321.    cur_window := saved_window.win;
  322.    old_window(cur_window);
  323.  
  324. (* restore the cursor position *)
  325.    gotoxy(saved_window.cux,saved_window.cuy);
  326.  
  327. (* restore the display contents *)
  328.    disp_mem^ := saved_window.scr;
  329.  
  330. (* restore current video mode *)
  331.    if cur_window.attr = low_attr then
  332.       lowvideo
  333.    else
  334.       normvideo;
  335. end;
  336.  
  337.  
  338. procedure preserve_screen(name: popup_string);
  339.                                 {preserve contents in a named file}
  340. var
  341.    fd:  file of window_save_rec;
  342.  
  343. begin
  344.    if invisible then
  345.       exit;
  346.  
  347.    assign(fd,name);
  348. {$I-}
  349.    rewrite(fd);
  350. {$I+}
  351.    if ioresult = 0 then
  352.    begin
  353.       open_pop_up(1,1,5,5,'');
  354.       remove_pop_up;
  355.       write(fd,saved_window);
  356.       close(fd);
  357.    end;
  358. end;
  359.  
  360.  
  361. procedure restore_screen(name: popup_string);
  362.                                {restore a preserved screen from a file;
  363.                                 don't touch screen if file is missing}
  364. var
  365.    fd:  file of window_save_rec;
  366.  
  367. begin
  368.    if invisible then
  369.       exit;
  370.  
  371.    assign(fd,name);
  372. {$I-}
  373.    reset(fd);
  374. {$I+}
  375.    if ioresult = 0 then
  376.    begin
  377.       read(fd,saved_window);
  378.       close(fd);
  379.       remove_pop_up;
  380.    end;
  381.  
  382. end;
  383.  
  384.  
  385. procedure init_pop_up;   {call once before anything else in this library}
  386. begin
  387.    window(1,1,80,25);
  388.    normvideo;
  389. end;
  390.  
  391.